package ER.diagram.part;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.gmf.runtime.notation.View;

import ER.ERDiagram;
import ER.ERPackage;
import ER.Entity;
import ER.PrimaryKey;
import ER.Relation;
import ER.diagram.edit.parts.ColumnsEditPart;
import ER.diagram.edit.parts.ERDiagramEditPart;
import ER.diagram.edit.parts.EntityColumnCompartmentEditPart;
import ER.diagram.edit.parts.EntityEditPart;
import ER.diagram.edit.parts.EntityPrimaryKeyCompartmentEditPart;
import ER.diagram.edit.parts.PrimaryKeyEditPart;
import ER.diagram.edit.parts.RelationEditPart;
import ER.diagram.providers.EntityRelationshipElementTypes;

/**
 * @generated
 */
public class EntityRelationshipDiagramUpdater {

	/**
	 * @generated
	 */
	public static List<EntityRelationshipNodeDescriptor> getSemanticChildren(
			View view) {
		switch (EntityRelationshipVisualIDRegistry.getVisualID(view)) {
		case ERDiagramEditPart.VISUAL_ID:
			return getERDiagram_1000SemanticChildren(view);
		case EntityColumnCompartmentEditPart.VISUAL_ID:
			return getEntityColumnCompartment_7001SemanticChildren(view);
		case EntityPrimaryKeyCompartmentEditPart.VISUAL_ID:
			return getEntityPrimaryKeyCompartment_7002SemanticChildren(view);
		}
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipNodeDescriptor> getERDiagram_1000SemanticChildren(
			View view) {
		if (!view.isSetElement()) {
			return Collections.emptyList();
		}
		ERDiagram modelElement = (ERDiagram) view.getElement();
		LinkedList<EntityRelationshipNodeDescriptor> result = new LinkedList<EntityRelationshipNodeDescriptor>();
		for (Iterator<?> it = modelElement.getEntities().iterator(); it
				.hasNext();) {
			Entity childElement = (Entity) it.next();
			int visualID = EntityRelationshipVisualIDRegistry.getNodeVisualID(
					view, childElement);
			if (visualID == EntityEditPart.VISUAL_ID) {
				result.add(new EntityRelationshipNodeDescriptor(childElement,
						visualID));
				continue;
			}
		}
		return result;
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipNodeDescriptor> getEntityColumnCompartment_7001SemanticChildren(
			View view) {
		if (false == view.eContainer() instanceof View) {
			return Collections.emptyList();
		}
		View containerView = (View) view.eContainer();
		if (!containerView.isSetElement()) {
			return Collections.emptyList();
		}
		Entity modelElement = (Entity) containerView.getElement();
		LinkedList<EntityRelationshipNodeDescriptor> result = new LinkedList<EntityRelationshipNodeDescriptor>();
		for (Iterator<?> it = modelElement.getColumns().iterator(); it
				.hasNext();) {
			ER.columns childElement = (ER.columns) it.next();
			int visualID = EntityRelationshipVisualIDRegistry.getNodeVisualID(
					view, childElement);
			if (visualID == ColumnsEditPart.VISUAL_ID) {
				result.add(new EntityRelationshipNodeDescriptor(childElement,
						visualID));
				continue;
			}
		}
		return result;
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipNodeDescriptor> getEntityPrimaryKeyCompartment_7002SemanticChildren(
			View view) {
		if (false == view.eContainer() instanceof View) {
			return Collections.emptyList();
		}
		View containerView = (View) view.eContainer();
		if (!containerView.isSetElement()) {
			return Collections.emptyList();
		}
		Entity modelElement = (Entity) containerView.getElement();
		LinkedList<EntityRelationshipNodeDescriptor> result = new LinkedList<EntityRelationshipNodeDescriptor>();
		for (Iterator<?> it = modelElement.getKeys().iterator(); it.hasNext();) {
			PrimaryKey childElement = (PrimaryKey) it.next();
			int visualID = EntityRelationshipVisualIDRegistry.getNodeVisualID(
					view, childElement);
			if (visualID == PrimaryKeyEditPart.VISUAL_ID) {
				result.add(new EntityRelationshipNodeDescriptor(childElement,
						visualID));
				continue;
			}
		}
		return result;
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipLinkDescriptor> getContainedLinks(
			View view) {
		switch (EntityRelationshipVisualIDRegistry.getVisualID(view)) {
		case ERDiagramEditPart.VISUAL_ID:
			return getERDiagram_1000ContainedLinks(view);
		case EntityEditPart.VISUAL_ID:
			return getEntity_2001ContainedLinks(view);
		case ColumnsEditPart.VISUAL_ID:
			return getColumns_3001ContainedLinks(view);
		case PrimaryKeyEditPart.VISUAL_ID:
			return getPrimaryKey_3002ContainedLinks(view);
		case RelationEditPart.VISUAL_ID:
			return getRelation_4001ContainedLinks(view);
		}
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipLinkDescriptor> getIncomingLinks(
			View view) {
		switch (EntityRelationshipVisualIDRegistry.getVisualID(view)) {
		case EntityEditPart.VISUAL_ID:
			return getEntity_2001IncomingLinks(view);
		case ColumnsEditPart.VISUAL_ID:
			return getColumns_3001IncomingLinks(view);
		case PrimaryKeyEditPart.VISUAL_ID:
			return getPrimaryKey_3002IncomingLinks(view);
		case RelationEditPart.VISUAL_ID:
			return getRelation_4001IncomingLinks(view);
		}
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipLinkDescriptor> getOutgoingLinks(
			View view) {
		switch (EntityRelationshipVisualIDRegistry.getVisualID(view)) {
		case EntityEditPart.VISUAL_ID:
			return getEntity_2001OutgoingLinks(view);
		case ColumnsEditPart.VISUAL_ID:
			return getColumns_3001OutgoingLinks(view);
		case PrimaryKeyEditPart.VISUAL_ID:
			return getPrimaryKey_3002OutgoingLinks(view);
		case RelationEditPart.VISUAL_ID:
			return getRelation_4001OutgoingLinks(view);
		}
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipLinkDescriptor> getERDiagram_1000ContainedLinks(
			View view) {
		ERDiagram modelElement = (ERDiagram) view.getElement();
		LinkedList<EntityRelationshipLinkDescriptor> result = new LinkedList<EntityRelationshipLinkDescriptor>();
		result.addAll(getContainedTypeModelFacetLinks_Relation_4001(modelElement));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipLinkDescriptor> getEntity_2001ContainedLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipLinkDescriptor> getColumns_3001ContainedLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipLinkDescriptor> getPrimaryKey_3002ContainedLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipLinkDescriptor> getRelation_4001ContainedLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipLinkDescriptor> getEntity_2001IncomingLinks(
			View view) {
		Entity modelElement = (Entity) view.getElement();
		Map<EObject, Collection<EStructuralFeature.Setting>> crossReferences = EcoreUtil.CrossReferencer
				.find(view.eResource().getResourceSet().getResources());
		LinkedList<EntityRelationshipLinkDescriptor> result = new LinkedList<EntityRelationshipLinkDescriptor>();
		result.addAll(getIncomingTypeModelFacetLinks_Relation_4001(
				modelElement, crossReferences));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipLinkDescriptor> getColumns_3001IncomingLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipLinkDescriptor> getPrimaryKey_3002IncomingLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipLinkDescriptor> getRelation_4001IncomingLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipLinkDescriptor> getEntity_2001OutgoingLinks(
			View view) {
		Entity modelElement = (Entity) view.getElement();
		LinkedList<EntityRelationshipLinkDescriptor> result = new LinkedList<EntityRelationshipLinkDescriptor>();
		result.addAll(getOutgoingTypeModelFacetLinks_Relation_4001(modelElement));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipLinkDescriptor> getColumns_3001OutgoingLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipLinkDescriptor> getPrimaryKey_3002OutgoingLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<EntityRelationshipLinkDescriptor> getRelation_4001OutgoingLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	private static Collection<EntityRelationshipLinkDescriptor> getContainedTypeModelFacetLinks_Relation_4001(
			ERDiagram container) {
		LinkedList<EntityRelationshipLinkDescriptor> result = new LinkedList<EntityRelationshipLinkDescriptor>();
		for (Iterator<?> links = container.getRelations().iterator(); links
				.hasNext();) {
			EObject linkObject = (EObject) links.next();
			if (false == linkObject instanceof Relation) {
				continue;
			}
			Relation link = (Relation) linkObject;
			if (RelationEditPart.VISUAL_ID != EntityRelationshipVisualIDRegistry
					.getLinkWithClassVisualID(link)) {
				continue;
			}
			Entity dst = link.getDestiny();
			Entity src = link.getOrigin();
			result.add(new EntityRelationshipLinkDescriptor(src, dst, link,
					EntityRelationshipElementTypes.Relation_4001,
					RelationEditPart.VISUAL_ID));
		}
		return result;
	}

	/**
	 * @generated
	 */
	private static Collection<EntityRelationshipLinkDescriptor> getIncomingTypeModelFacetLinks_Relation_4001(
			Entity target,
			Map<EObject, Collection<EStructuralFeature.Setting>> crossReferences) {
		LinkedList<EntityRelationshipLinkDescriptor> result = new LinkedList<EntityRelationshipLinkDescriptor>();
		Collection<EStructuralFeature.Setting> settings = crossReferences
				.get(target);
		for (EStructuralFeature.Setting setting : settings) {
			if (setting.getEStructuralFeature() != ERPackage.eINSTANCE
					.getRelation_Destiny()
					|| false == setting.getEObject() instanceof Relation) {
				continue;
			}
			Relation link = (Relation) setting.getEObject();
			if (RelationEditPart.VISUAL_ID != EntityRelationshipVisualIDRegistry
					.getLinkWithClassVisualID(link)) {
				continue;
			}
			Entity src = link.getOrigin();
			result.add(new EntityRelationshipLinkDescriptor(src, target, link,
					EntityRelationshipElementTypes.Relation_4001,
					RelationEditPart.VISUAL_ID));
		}
		return result;
	}

	/**
	 * @generated
	 */
	private static Collection<EntityRelationshipLinkDescriptor> getOutgoingTypeModelFacetLinks_Relation_4001(
			Entity source) {
		ERDiagram container = null;
		// Find container element for the link.
		// Climb up by containment hierarchy starting from the source
		// and return the first element that is instance of the container class.
		for (EObject element = source; element != null && container == null; element = element
				.eContainer()) {
			if (element instanceof ERDiagram) {
				container = (ERDiagram) element;
			}
		}
		if (container == null) {
			return Collections.emptyList();
		}
		LinkedList<EntityRelationshipLinkDescriptor> result = new LinkedList<EntityRelationshipLinkDescriptor>();
		for (Iterator<?> links = container.getRelations().iterator(); links
				.hasNext();) {
			EObject linkObject = (EObject) links.next();
			if (false == linkObject instanceof Relation) {
				continue;
			}
			Relation link = (Relation) linkObject;
			if (RelationEditPart.VISUAL_ID != EntityRelationshipVisualIDRegistry
					.getLinkWithClassVisualID(link)) {
				continue;
			}
			Entity dst = link.getDestiny();
			Entity src = link.getOrigin();
			if (src != source) {
				continue;
			}
			result.add(new EntityRelationshipLinkDescriptor(src, dst, link,
					EntityRelationshipElementTypes.Relation_4001,
					RelationEditPart.VISUAL_ID));
		}
		return result;
	}

}
